package com.xuecheng.content.service.jobhandler;

import com.xuecheng.api.client.MediaClient;
import com.xuecheng.api.client.SearchClient;
import com.xuecheng.base.result.RestResponse;
import com.xuecheng.content.constant.CourseCacheConstant;
import com.xuecheng.message.sdk.constant.MqMessageTypeConstant;
import com.xuecheng.message.sdk.model.po.MqMessage;
import com.xuecheng.message.sdk.service.IMqMessageService;
import com.xuecheng.message.sdk.service.MessageProcessAbstract;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @author 勾新杰
 * @version 1.0
 * @description: 长时间下架的课程任务
 * @date 2025/2/19 10:26
 */
@Slf4j
@Component
public class CourseOfflineTask extends MessageProcessAbstract {

    /**
     * 媒资客户端
     */
    private final MediaClient mediaClient;

    /**
     * 搜索客户端
     */
    private final SearchClient searchClient;

    /**
     * 缓存客户端
     */
    private final RedisTemplate<String, String> redisTemplate;

    /**
     * 构造函数依赖注入
     *
     * @param mqMessageService 消息服务
     * @param mediaClient      媒资客户端
     * @param redisTemplate
     */
    @Autowired
    public CourseOfflineTask(IMqMessageService mqMessageService,
                             MediaClient mediaClient,
                             SearchClient searchClient, RedisTemplate<String, String> redisTemplate) {
        super(mqMessageService);
        this.mediaClient = mediaClient;
        this.searchClient = searchClient;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 长时间下架的课程任务
     */
    @XxlJob("CourseOfflineJobHandler")
    public void courseOfflineJobHandler() {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex = " + shardIndex + ", shardTotal = " + shardTotal);
        // 参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间(分钟)
        int count = Runtime.getRuntime().availableProcessors();
        process(shardIndex, shardTotal, MqMessageTypeConstant.MESSAGE_TYPE_COURSE_OFFLINE, count, 60);
    }

    /**
     * 执行任务
     *
     * @param mqMessage 执行任务内容
     * @return boolean true:处理成功，false处理失败
     */
    @Override
    public boolean execute(MqMessage mqMessage) {
        Long courseId = Long.valueOf(mqMessage.getBusinessKey1());
        try {
            // 2. 清理课程静态化
            clearStaticHtml(mqMessage, courseId);
            // 3. 清理课程索引
            clearCourseIndex(mqMessage, courseId);
            // 4. 清理课程缓存
            clearCourseCache(mqMessage, courseId);
        } catch (RuntimeException e) {
            return false;
        }
        getMqMessageService().success(mqMessage.getId());
        return true;
    }

    /**
     * 清理课程静态页面
     *
     * @param mqMessage 消息
     * @param courseId  课程id
     */
    private void clearStaticHtml(MqMessage mqMessage, Long courseId) {
        log.debug("开始清理课程静态页面,课程id:{}", courseId);
        Long id = mqMessage.getId();
        IMqMessageService mqMessageService = getMqMessageService();
        // 1. 如果静态页面已经清理过，直接返回
        if (mqMessageService.getStageOne(id) > 0) {
            log.debug("清理课程静态页面已处理直接返回，课程id:{}", courseId);
            return;
        }
        // 2. 清理课程静态页面
        RestResponse<Boolean> response = mediaClient.deleteCourseHtml(courseId);
        // 2.1 清理成功
        if (response.isSuccessful() && response.getResult()) {
            mqMessageService.completedStageOne(id);
        }
        // 2.2 清理失败
        else {
            log.error("清理课程静态页面失败，课程id:{}", courseId);
            mqMessageService.fail(id, "清理课程静态页面失败");
            throw new RuntimeException();
        }
    }

    /**
     * 清理课程索引
     *
     * @param mqMessage 消息
     * @param courseId  课程id
     */
    private void clearCourseIndex(MqMessage mqMessage, Long courseId) {
        log.debug("清理课程索引信息,课程id:{}", courseId);
        Long id = mqMessage.getId();
        IMqMessageService mqMessageService = this.getMqMessageService();
        // 1. 如果课程索引已经清理过，直接返回
        if (mqMessageService.getStageTwo(id) > 0) {
            log.debug("课程索引已清理，直接返回，课程id:{}", courseId);
            return;
        }
        // 2. 清理课程索引
        Boolean delete = searchClient.delete(String.valueOf(courseId));
        if (!delete) {
            log.error("清理课程索引失败，课程id:{}", courseId);
            mqMessageService.fail(id, "清理课程索引失败");
            throw new RuntimeException();
        }
        // 3. 记录第二阶段状态：已完成
        mqMessageService.completedStageTwo(id);
    }

    /**
     * 清理课程缓存
     *
     * @param mqMessage 消息
     * @param courseId  课程id
     */
    private void clearCourseCache(MqMessage mqMessage, Long courseId) {
        log.debug("清理课程缓存,课程id:{}", courseId);
        Long id = mqMessage.getId();
        IMqMessageService mqMessageService = this.getMqMessageService();
        if (mqMessageService.getStageThree(id) > 0) {
            log.debug("课程缓存已清理，直接返回，课程id:{}", courseId);
            return;
        }
        try {
            redisTemplate.delete(CourseCacheConstant.KEY_PREFIX + courseId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        mqMessageService.completedStageThree(id);
    }
}
